#include "stm32regbit.h"
#include "stm32regs.h"

void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset)
{
  SCB->VTOR = NVIC_VectTab | (Offset & (u32)0xFFFFFE00); //设置NVIC的向量表偏移寄存器,VTOR低9位保留,即[8:0]保留。
}

void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{
  u32 temp, temp1;
  temp1 = (~NVIC_Group) & 0x07; //取后三位
  temp1 <<= 8;
  temp = SCB->AIRCR;  //读取先前的设置
  temp &= 0X0000F8FF; //清空先前分组
  temp |= 0X05FA0000; //写入钥匙
  temp |= temp1;
  SCB->AIRCR = temp; //设置分组
}

void MY_NVIC_Init(u8 NVIC_PreemptionPriority, u8 NVIC_SubPriority, u8 NVIC_Channel, u8 NVIC_Group)
{
  u32 temp;
  MY_NVIC_PriorityGroupConfig(NVIC_Group); //设置分组
  temp = NVIC_PreemptionPriority << (4 - NVIC_Group);
  temp |= NVIC_SubPriority & (0x0f >> NVIC_Group);
  temp &= 0xf;                                             //取低四位
  NVIC->ISER[NVIC_Channel / 32] |= 1 << NVIC_Channel % 32; //使能中断位(要清除的话,设置ICER对应位为1即可)
  NVIC->IP[NVIC_Channel] |= temp << 4;                     //设置响应优先级和抢断优先级
}

void GPIO_Set(GPIO_TypeDef *GPIOx, u32 BITx, u32 MODE, u32 OTYPE, u32 OSPEED, u32 PUPD)
{
  u32 pinpos = 0, pos = 0, curpin = 0;
  for (pinpos = 0; pinpos < 16; pinpos++)
  {
    pos = 1 << pinpos;   //一个个位检查
    curpin = BITx & pos; //检查引脚是否要设置
    if (curpin == pos)   //需要设置
    {
      GPIOx->MODER &= ~(3 << (pinpos * 2)); //先清除原来的设置
      GPIOx->MODER |= MODE << (pinpos * 2); //设置新的模式
      if ((MODE == 0X01) || (MODE == 0X02)) //如果是输出模式/复用功能模式
      {
        GPIOx->OSPEEDR &= ~(3 << (pinpos * 2));     //清除原来的设置
        GPIOx->OSPEEDR |= (OSPEED << (pinpos * 2)); //设置新的速度值
        GPIOx->OTYPER &= ~(1 << pinpos);            //清除原来的设置
        GPIOx->OTYPER |= OTYPE << pinpos;           //设置新的输出模式
      }
      GPIOx->PUPDR &= ~(3 << (pinpos * 2)); //先清除原来的设置
      GPIOx->PUPDR |= PUPD << (pinpos * 2); //设置新的上下拉
    }
  }
}

void GPIO_AF_Set(GPIO_TypeDef *GPIOx, u8 BITx, u8 AFx)
{
  GPIOx->AFR[BITx >> 3] &= ~(0X0F << ((BITx & 0X07) * 4));
  GPIOx->AFR[BITx >> 3] |= (u32)AFx << ((BITx & 0X07) * 4);
}